function PolygonEngine(ctx){
	
	this.ctx = null;
	this.data = null;
	this.controller = null;
	this.search = new EngineSearch();
	
	this.initCanvas = function(canvasName){
		canvas = document.getElementById(canvasName);
		if( (canvas && canvas.getContext) == false ) {
			alert("your browser does not supports html5 canvas");
			return false;
		}
		ctx = canvas.getContext("2d");
		ctx.fillStyle = "rgb(255,255,255)";
		ctx.fillRect(0,0,400,400);
		ctx.strokeStyle = "rgb(0,0,0)";
		this.ctx = ctx;
		return true;
	};
	
	this.loadVertices = function(arr){
		this.data = [];
		for(var i=0; i <arr.length; i++){
			var temp = new Polygon();
			for ( var property in arr[i] ){
				temp[property] = arr[i][property];
			}
			this.data.push(temp);
		}
	};	
	
	this.display = function(){
		for( var i = 0; i < this.data.length; i++){
			var p = this.data[i];
			p = this.setPoints3D(p);
			p = this.project(p);
			p = this.createAverageZ(p);
			this.data[i] = p;
		}
		
		this.data.sort(this.sortByAvg_z);
		this.ctx.fillStyle = "rgb(255,255,255)";
		this.ctx.fillRect(0,0,400,400);
		for( var i = 0; i < this.data.length; i++){
			this.render(this.data[i]);
		}
		
		if(this.search.inProcess){
			this.search.end();
			this.controller.updateFromSearch(this.search.requestList);
			this.search.reset();
		}
		
		stats.update(); //TODO:remove
	};
	
	this.render = function(polygonObj){
		this.ctx.fillStyle = "rgb(0,0,0)"; //polygonObj.color;
		this.ctx.beginPath();
		this.ctx.moveTo(polygonObj.points3D[0].x, polygonObj.points3D[0].y);
		for(var i=1; i < polygonObj.points3D.length; i++){
			this.ctx.lineTo(polygonObj.points3D[i].x, polygonObj.points3D[i].y);
		}
		this.ctx.closePath();
		if(this.search.inProcess){
			this.search.processMouseInputEvents(this.ctx, polygonObj);
		}
		var renderMethod = polygonObj.renderMethod;
		this.ctx[renderMethod]();
		//this.ctx.stroke();
		//if(polygonObj.id == 2)
			polygonObj.createCurveControlPoints(this.ctx);
	};
	
	
	
	this.arrayToRGB = function(arr) {
		if( arr.length == 3 ) {
			return "rgb(" + arr[0] + "," + arr[1] + "," + arr[2] + ")";
		}
		return "rgb(0,0,0)";
	};
	
	this.sortByAvg_z = function(a,b){
		return b.avg_z - a.avg_z;
	};
	
	this.createAverageZ = function(polygonObj){
		var temp = 0;
		for( var i = 0; i < polygonObj.points.length; i++){
			temp += polygonObj.points3D[i].z;
		}
		polygonObj.avg_z = temp / polygonObj.points.length;
		return polygonObj;
	};
	
	this.setPoints3D = function(polygonObj){
		polygonObj.points3D = [];
		for( var i = 0; i < polygonObj.points.length; i++){
			polygonObj.points3D.push(new Point3D(polygonObj.points[i][0], polygonObj.points[i][1], polygonObj.points[i][2]));
		}
		return polygonObj;
	};
	
	this.project = function(polygonObj){
		for( var i = 0; i < polygonObj.points3D.length; i++ ) {
			var v = polygonObj.points3D[i];
			//var r = v.rotateX(angle).rotateY(angle).rotateZ(angle); //used in demo mode
			var r = v.rotateX(axis_x).rotateY(axis_y).rotateZ(axis_z);
			var p = r.project(viewWidth, viewHeight, fov, viewDistance);//viewWidth, viewHeight, fov, viewDistance
			polygonObj.points3D[i] = p;
		}
		return polygonObj;
	};
	
	this.setController = function(c){
		this.controller = c;
	};
	
}

